# @Version : 1.0
# @Author  : wxz
# @File    : oauth2.py
# @Time    : 2025/5/30 9:06
# @Describe: 描述...
from typing import Optional

from fastapi import HTTPException
from fastapi.security import OAuth2PasswordBearer
from fastapi.security.utils import get_authorization_scheme_param
from starlette.requests import Request
from starlette.status import HTTP_401_UNAUTHORIZED

from config import app_settings


class OAuth2(OAuth2PasswordBearer):
    """
    对于doc文档中需要登录后才能访问的API接口，需要添加OAuth2PasswordBearer依赖项
    自定义此类，并继承OAuth2PasswordBearer，重写父类的call方法，实现自身业务的token验证
    """

    def __init__(self, tokenUrl: str, schema: str):
        """

        :param tokenUrl: 接口文档中，表单提交请求的路由
        :param schema: Token的实现技术，本项目中采用JWT
        """
        super().__init__(tokenUrl, schema)

    async def __call__(self, request: Request) -> Optional[str]:
        """
        解析请求头中的 token
        :param request:
        :return:
        """
        path:str = request.url.path
        # 如果请求地址不在 no_access_token_urls 中，则需要token令牌验证
        if path not in app_settings.no_access_token_urls:
            authorization = request.headers.get("Authorization")
            scheme, param = get_authorization_scheme_param(authorization)
            if not authorization or scheme.lower() != "bearer":
                if self.auto_error:
                    raise HTTPException(
                        status_code=HTTP_401_UNAUTHORIZED,
                        detail="Not authenticated",
                        headers={"WWW-Authenticate": "Bearer"},
                    )
                else:
                    return None
            return param
        else:
            return ''




